package com.bjpowernode.money.service;

import com.alibaba.dubbo.config.annotation.Service;
import com.bjpowernode.money.Constant;
import com.bjpowernode.money.PageModel;
import com.bjpowernode.money.mapper.BidInfoMapper;
import com.bjpowernode.money.mapper.FinanceAccountMapper;
import com.bjpowernode.money.mapper.LoanInfoMapper;
import com.bjpowernode.money.model.BidInfo;
import com.bjpowernode.money.model.LoanInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service(interfaceClass = BidInfoService.class,version = "1.0.0",timeout = 20000)
@Component
public class BidInfoServiceImpl implements BidInfoService {

    @Autowired
    BidInfoMapper bidInfoMapper;
    @Autowired
    RedisTemplate redisTemplate;
    @Autowired
    FinanceAccountMapper financeAccountMapper;
    @Autowired
    LoanInfoMapper loanInfoMapper;

    // 首页显示 累计成交额(取出数据后存放在 Redis中)
    @Override
    public Double queryBidInfoMoneySum() {

        //设置redisTemplate对象key的序列化方式  使在存存储到redis中时名字
        redisTemplate.setKeySerializer(new StringRedisSerializer());

        //从redis中查询累计成交额
        Double bidInfoMoneySum = (Double) redisTemplate.opsForValue().get("bidInfoMoneySum");

        //判断
        if(bidInfoMoneySum==null){
            //加锁
            synchronized (this){
                //双重判断 防止缓存刺透
                if(bidInfoMoneySum==null){
                    //从数据库中查询
                    bidInfoMoneySum = bidInfoMapper.selectBidInfoMoneySum();
                    //将数据库中查询出的结果放在redis中
                    redisTemplate.opsForValue().set("bidInfoMoneySum",bidInfoMoneySum,15, TimeUnit.SECONDS);
                }
            }
        }

        return bidInfoMoneySum;
    }

    //产品详情页面，根据loadId查询对应的投资信息
    @Override
    public List<BidInfo> queryBidInfoByLoadId(int loanId, PageModel pageModel) {

        Long start = (pageModel.getCunPage() - 1)*pageModel.getPageSize();
        Integer content = pageModel.getPageSize();


        return bidInfoMapper.selectBidInfoByLoadId(loanId,start,content);
    }

    // 详情页面 实现分页 查找对应的投资信息数量
    @Override
    public Long queryBidInfoCountByLoadId(int loanId) {
        return bidInfoMapper.selectBidInfoCountByLoadId(loanId);
    }

    /**
     * 1、账户余额减少
     * 2、剩余可投金额减少（判断是否满标）
     * 3、添加投资记录
     * @param parasMap
     * @return
     */
    @Override
    @Transactional
    public String invest(Map<String, Object> parasMap) {

//       课后：完成！
//        Map map;
//        LoanInfo loanInfo=map.get(loanId);
//        if(loanInfo==null){
//            loanInfo=new LoanInfo();
//            map.put(loanId,loanInfo);
//        }

        // synchronized (loanInfo){  this:别的产品也不能投资了
        //financeAccoutMapper.updateAvailableMoneyReduceByUserIdForInvest(parasMap);:不需要同步，没有出现并发（多终端同时购买 除外）
        //  num=loanInfoMapper.updateLeftMoneyReduceByIdForInvest(parasMap);存在并发
        // loanInfoMapper.updateByPrimaryKeySelective(loanInfo);存在并发，不需要同步（因为数据没有出现不安全）
        //    num= bidInfoMapper.insertSelective(bidInfo);没有并发，不需要同步
        //}

        //1、账户余额减少
        int num=financeAccountMapper.updateAvailableMoneyReduceByUserIdForInvest(parasMap);
        if(num==0){
            //throw new financeAccoutException();
            //return "no  ok";

            //事务回滚
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Constant.BID_FINANCE_MONEY_NOT_MUCH;
        }

        //2、剩余可投金额减少
        num=loanInfoMapper.updateLeftMoneyReduceByIdForInvest(parasMap);

        //3、判断是否满标
        LoanInfo loanInfo = loanInfoMapper.selectByPrimaryKey((Integer) parasMap.get("loanId"));
        if(loanInfo.getLeftProductMoney()<=0&&loanInfo.getProductStatus()==0){
            loanInfo.setProductStatus(1);
            loanInfo.setProductFullTime(new Date());
            num=  loanInfoMapper.updateByPrimaryKeySelective(loanInfo);
        }

        //4、添加投资记录
        BidInfo bidInfo=new BidInfo();
        bidInfo.setBidMoney((Double) parasMap.get("bidMoney"));
        bidInfo.setBidStatus(1);
        bidInfo.setBidTime(new Date());
        bidInfo.setLoanId((Integer) parasMap.get("loanId"));
        bidInfo.setUid((Integer) parasMap.get("userId"));
        num= bidInfoMapper.insertSelective(bidInfo);
        if(num==0){
            //事务回滚
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Constant.BID_BID_INFO_ERROR;
        }

        return Constant.BID_BID_INFO_SUCCESS;
    }


}
